<link rel="ractive" href="../shared/header.html" name="Header">

<Header app="{{app}}" query="{{query}}"></Header>

<div class="debug-tool tools">
	<div class="container">
		<div class="row">
			<div class="col-md-12 col-md-offset-6 col-xs-16 col-xs-offset-4">
				<h1 class="text-center">Debug tool</h1>

				<div class="debug-tool-results">
					{{#if progress !== 100}}
						<div class="running-tests">
							Running tests...

							<div class="progress">
								<div class="progress-bar" role="progressbar" style="width: {{progress}}%"></div>
							</div>
						</div>
					{{else}}
						<div class="debug-tool-results-header">
							<button on-click="test()" class="btn btn-default">
								<i class="fa fa-refresh"></i>Reload
							</button>

							{{#if hasFlash}}
								<button class="btn btn-default" decorator="zeroClipboard" data-clipboard-text="{{link}}">
									<i class="fa fa-copy"></i>Copy
								</button>
							{{/if hasFlash}}

							{{#if saved}}
								Showing results for IP address <strong>{{results.ipInfo.ip}}</strong> from {{results.now}}.
							{{/if saved}}
						</div>

						<div class="debug-tool-results-body">
							<span class="results-date">{{results.now}}</span><br>

							{{#with results.ipInfo}}
								<br><strong>{{tests.ipInfo}}</strong><br>

								{{#if error}}
									{{error}}<br>
								{{else}}
									{{#each this}}
										{{@key}}: {{this}}<br>
									{{/each this}}
								{{/if error}}
							{{/with results.ipInfo}}

							<br><strong>{{tests.server}}</strong><br>
							{{results.server}}<br>

							{{#with results.dns}}
								<br><strong>{{dnsTests.dns}}</strong><br>
								{{this}}<br>
							{{/with results.dns}}

							{{#each results.servers}}
								<br><strong>{{tests.servers[@index]}}</strong><br>
								{{this}}<br>
							{{/each results.servers}}

							{{#each results.availability}}
								<br><strong>{{dnsTests.availability[@index]}}</strong><br>

								{{#if error}}
									{{error}}<br>
								{{else}}
									{{#each this}}
										{{@key}}: {{this}}<br>
									{{/each this}}
								{{/if error}}
							{{/each results.availability}}

							{{#each results.performance}}
								<br><strong>{{dnsTests.performance[@index]}}</strong><br>
								{{this}}<br>
							{{/each results.performance}}
						</div>
					{{/if}}
				</div>
			</div>
		</div>
	</div>
</div>

<script>
	var testString = require('public/js/utils/test-string.js');
	var zeroClipboardDecorator = require('public/js/decorators/zero-clipboard.js');

	component.exports = {
		decorators: {
			zeroClipboard: zeroClipboardDecorator
		},
		computed: {
			dnsTests: function () {
				var ip = this.get('results.ipInfo.ip').replace(/\./g, '-');
				var tests = {
					dns: '2-01-2cd3-000f.cdx-i-' + ip + '.cedexis.net',
					availability: [],
					performance: []
				};

				$.each(this.get('providers'), function (index, provider) {
					tests.availability.push(provider + '.avail.2-01-2cd3-0010.cdx-i-' + ip + '.cedexis.net');
					tests.performance.push(provider + '.http_rtt.2-01-2cd3-0010.cdx-i-' + ip + '.cedexis.net')
				});

				return tests;
			},
			progress: function () {
				var results = this.get('results');

				return (
					!!results.ipInfo
					+ !!results.server
					+ !!results.dns
					+ results.servers.concat(results.availability, results.performance).filter(function (i) { return i; }).length
				) / this.get('total') * 100;
			},
			resultsHash: {
				get: function () {
					if (this.get('progress') === 100) {
						return this.get('results');
					}
				},
				set: function (value) {
					this.set('results', value)
				}
			},
			total: function () {
				return 2 + this.get('tests.servers').length + 1 + 8;
			}
		},
		data: function () {
			return {
				title: 'Debug tool - jsDelivr',
				link: '',
				providers: [ 'cloudflare', 'maxcdn', 'keycdn', 'quantil' ],
				results: {
					availability: [],
					performance: [],
					servers: [],
				},
				tests: {
					ipInfo: 'http://ipinfo.io/json',
					server: 'http://cdn.jsdelivr.net/information.txt',
					servers: [
						'https://cdn.jsdelivr.net/r15lgc.js',
						'http://cdn.jsdelivr.net/r15lgc.js',
						'http://testingcf.jsdelivr.net/r15lgc.js',
						'http://jsdelivr3.dak.netdna-cdn.com/r15lgc.js',
						'http://jsdelivr-cb7.kxcdn.com/r15lgc.js',
						'http://quantil.jsdelivr.net/r15lgc.js',
					]
				}
			};
		},
		oninit: function () {
			if (!Ractive.isServer) {
				var _this = this;

				this.set('hasFlash', !ZeroClipboard.isFlashUnusable());

				this.observe('progress', function (value) {
					if (value === 100) {
						this.set('link', location.href);

						// Google is smart enough to return an existing URL if there is one.
						$.ajax({
							type: 'POST',
							contentType: 'application/json; charset=UTF-8',
							url: 'https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyB8DINjLBVWS7ImklEB1zOAS8QyuIGzB-Q',
							data: JSON.stringify({ longUrl: location.href }),
							success: function (response) {
								if (response.id) {
									_this.set('link', response.id);
								}
							}
						});
					}
				}, { defer: true });

				if (this.get('progress') === 100) {
					this.set('saved', true);
				} else {
					this.test();
				}
			}
		},
		test: function () {
			var _this = this;

			this.set({
				results: {
					now: new Date().toUTCString(),
					ipInfo: null,
					dns: null,
					availability: [],
					performance: [],
					server: null,
					servers: [],
				},
				saved: false,
			});

			$.ajax(this.get('tests.ipInfo'), {
				cache: false,
				success: function (response) {
					_this.set('results.ipInfo', response);
					_this.testDns();
				},
				error: function (jqXHR, textStatus, errorThrown) {
					_this.set('results.ipInfo', { error: errorThrown || textStatus });
				}
			});

			$.ajax(this.get('tests.server'), {
				cache: false,
				success: function (response, textStatus, jqXHR) {
					_this.set('results.server', jqXHR.getResponseHeader('POP') || jqXHR.getResponseHeader('Server') || 'Failed to identify the server.');
				},
				error: function (jqXHR, textStatus, errorThrown) {
					_this.set('results.server', errorThrown || textStatus);
				}
			});

			$.each(this.get('tests.servers'), function (index, entry) {
				$.ajax(entry, {
					cache: false,
					success: function (response) {
						_this.set('results.servers.' + index, response === testString ? 'OK' : 'Failed');
					},
					error: function (jqXHR, textStatus, errorThrown) {
						_this.set('results.servers.' + index, errorThrown || textStatus);
					}
				});
			});
		},
		testDns: function () {
			var _this = this;

			$.ajax('/api/dns', {
				cache: false,
				data: { domain: this.get('dnsTests.dns') },
				success: function (response) {
					_this.set('results.dns', response);
				},
				error: function (jqXHR, textStatus, errorThrown) {
					_this.set('results.dns', errorThrown || textStatus);
				}
			});

			$.each(this.get('dnsTests.availability'), function (index, entry) {
				$.ajax('/api/dns', {
					cache: false,
					data: { domain: entry },
					success: function (response) {
						var data = response.split('.');

						_this.set('results.availability.' + index, {
							availability: data[5] + '%',
							continent: data[0],
							country: data[1],
							asn: data[2],
						});
					},
					error: function (jqXHR, textStatus, errorThrown) {
						_this.set('results.availability.' + index, { error: errorThrown || textStatus });
					}
				});
			});

			$.each(this.get('dnsTests.performance'), function (index, entry) {
				$.ajax('/api/dns', {
					cache: false,
					data: { domain: entry },
					success: function (response) {
						_this.set('results.performance.' + index, response.split('.')[5] + ' ms');
					},
					error: function (jqXHR, textStatus, errorThrown) {
						_this.set('results.performance.' + index, errorThrown || textStatus);
					}
				});
			});
		}
	};
</script>
